package javax.core.security.aop;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.core.security.AuthorizationManager;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Slf4j
public abstract class AbstractAuthorizationInterceptor extends HandlerInterceptorAdapter {
    @Autowired
    protected AuthorizationManager authorizationManager;

    private String getTokenFromHttpHeader(HttpServletRequest request) {
        return request.getHeader("Authorization");
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        String url = request.getServletPath();
        if (isInCorrectUrl(url)) {
            response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            return false;
        }

        if (isIgnoredAuthUrl(url)) {
            return true;
        }

        String token = getTokenFromHttpHeader(request);
        Object userPrincipal = authorizationManager.authorize(token);

        if (userPrincipal != null) {
            boolean result = doAfterLoadPrincipal(request, response, handler, userPrincipal);
            if (!result) {
                log.error("Got some error in doAfterLoadPrincipal, url:{}", request.getServletPath());
            }
            return result;
        } else {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            return false;
        }
    }

    protected abstract boolean isIgnoredAuthUrl(String url);

    protected abstract boolean isInCorrectUrl(String url);

    /**
     * 一些在登录成功后的用户操作，在子类中实现，如果没有特殊操作可以什么都不做.
     * 如果返回false，则报错
     **/
    protected boolean doAfterLoadPrincipal(HttpServletRequest request, HttpServletResponse response, Object handler, Object userPrincipal) {
        return true;
    }
}
